package com.zerosoft.shuguang.serial;

import com.fazecast.jSerialComm.SerialPort;
import com.zerosoft.shuguang.config.SerialPortProperties;
import com.zerosoft.shuguang.service.MqttSendClient;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public class SerialPortManager {
    public static volatile boolean SERIAL_PORT_STATE = false;

    public static volatile SerialPort SERIAL_PORT_OBJECT = null;
    @Resource
    private SerialPortProperties serialPortProperties;

    public static SerialPortManager serialPortManager;

    final int SERIAL_BAUD_RATE = serialPortProperties.getBaudRate();
    final int SERIAL_DATA_BITS = 8;
    final int SERIAL_STOP_BITS = 1;
    final int SERIAL_PARITY = SerialPort.NO_PARITY;
    final int SERIAL_FLOW_CONTROL = SerialPort.FLOW_CONTROL_DISABLED;
    final int SERIAL_READ_TIMEOUT = 1000;
    final int SERIAL_WRITE_TIMEOUT = 1000;

    final public static int BUFF_LEN = 125;

    @Resource
    private MqttSendClient mqttSendClient;

    public static List<String> getSerialPortList() {
        // TODO: 实现获取串口列表的逻辑
        // 获得当前所有可用串口
        SerialPort[] serialPorts = SerialPort.getCommPorts();
        List<String> portNameList = new ArrayList<String>();
        // 将可用串口名添加到List并返回该List
        for(SerialPort serialPort:serialPorts) {
            System.out.println(serialPort.getSystemPortName());
            portNameList.add(serialPort.getSystemPortName());
        }
        //去重
        portNameList = portNameList.stream().distinct().collect(Collectors.toList());
        return portNameList;
    }

    public static void connectSerialPort(SerialPortProperties port,MqttSendClient client) {
        // TODO: 实现连接串口逻辑
        try {
            SerialPort serialPort = SerialPortManager.openSerialPort(port);
            TimeUnit.MILLISECONDS.sleep(2000);
            //给当前串口对象设置监听器
            serialPort.addDataListener(new SerialPortListener(new SerialPortCallback(client)));
            if(serialPort.isOpen()) {
                SERIAL_PORT_OBJECT = serialPort;
                SERIAL_PORT_STATE = true;
                System.out.println(port.getPort()+"-- start success");
//                MqttSendClient mqttSendClient = new MqttSendClient();
//                mqttSendClient.publish(true, "event/abc", "{\"msg\":\""+port.getPort()+"-- start success\"}");
//                serialPortManager.mqttSendClient.publish(false, "event/abc", "{\"msg\":\""+port.getPort()+"-- start success\"}");
            }
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

    public static SerialPort openSerialPort(SerialPortProperties port) {
        SerialPort serialPort = SerialPort.getCommPort(port.getPort());

        serialPort.setBaudRate(port.getBaudRate());

        if (!serialPort.isOpen()) { //开启串口
            serialPort.openPort(1000);
        }else{
            return serialPort;
        }
        serialPort.setFlowControl(port.getFlowControl());
        serialPort.setComPortParameters(port.getBaudRate(),
                port.getDataBits(), port.getStopBits(), port.getParity());
        serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING | SerialPort.TIMEOUT_WRITE_BLOCKING, port.getReadTimeout(), port.getWriteTimeout());
        return serialPort;
    }

    // 关闭串口
    public static void closeSerialPort() {
        if (SERIAL_PORT_OBJECT != null && SERIAL_PORT_OBJECT.isOpen()){
            SERIAL_PORT_OBJECT.closePort();
            SERIAL_PORT_STATE = false;
            SERIAL_PORT_OBJECT = null;
        }
    }

    // 发送字节数组
    public static void sendSerialPortData(byte[] content) {
        if (SERIAL_PORT_OBJECT != null && SERIAL_PORT_OBJECT.isOpen()){
            SERIAL_PORT_OBJECT.writeBytes(content, content.length);
        }
    }

    // 读取字节数组
    public static byte[] readSerialPortData() {
        if (SERIAL_PORT_OBJECT != null && SERIAL_PORT_OBJECT.isOpen()){
            byte[] reslutData = null;
            try {
                if (!SERIAL_PORT_OBJECT.isOpen()){return null;};
                int i=0;
                while (SERIAL_PORT_OBJECT.bytesAvailable() > 0 /*&& SERIAL_PORT_OBJECT.bytesAvailable()<BUFF_LEN*/ && i++ < 5) {
//                    System.out.println("waiting..."+SERIAL_PORT_OBJECT.bytesAvailable());
                    Thread.sleep(20);
                }
                byte[] readBuffer = /*new byte[BUFF_LEN];*/ new byte[SERIAL_PORT_OBJECT.bytesAvailable()];
                int numRead = SERIAL_PORT_OBJECT.readBytes(readBuffer, readBuffer.length);
                if (numRead > 0) {
                    reslutData = readBuffer;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return reslutData;
        }
        return null;
    }

    @PostConstruct
    public void init() {
        serialPortManager = this;
        serialPortManager.mqttSendClient = this.mqttSendClient;
    }
}
